package com.kfgj.hkp.common.interceptor;

import com.kfgj.hkp.common.auth.Token;
import com.kfgj.hkp.common.constants.ContextConstants;
import com.kfgj.hkp.common.context.CurrentContext;
import com.kfgj.hkp.common.context.RequestContext;
import com.kfgj.hkp.common.enums.ResponseMessage;
import com.kfgj.hkp.common.exception.BusinessException;
import com.kfgj.hkp.common.service.AbstractServiceResponse;
import com.kfgj.hkp.common.user.business.IBaseUserManager;
import com.kfgj.hkp.common.user.entity.BaseUserEntity;
import com.kfgj.hkp.common.utils.CookieHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @description TODO
 * @auth liwensihan
 * @date 2018/6/28 18:40
 * @version 1.0
 * @return
 */
public class AuthenticationInterceptor extends AbstractSpringInterceptor {

    /**
     * 需要校验的权限列表
     */
    public List<String> checkOrIgnoreUrl;

    /**
     * 如果为true表示要检查checkUrl是否有权限
     * 如果为否则坚持忽略
     */
    private Boolean check = Boolean.TRUE;

    @Autowired
    protected IBaseUserManager userManager;

    @Override
    public boolean preInterceptor(HttpServletRequest request, HttpServletResponse response, Object handler){

        HttpServletRequest req = request;



        String path = req.getRequestURI();

        if (StringUtils.isEmpty(path)) {
            path = req.getPathInfo();
        }

        if (StringUtils.isEmpty(path)) {
            path = req.getServletPath();
        }

        BaseUserEntity user = loadUser(req, response);

        if (user == null) {
            if (check){
                if (ObjectUtils.isEmpty(checkOrIgnoreUrl)
                        || !pathContainsUrl(checkOrIgnoreUrl,path)){
                    throw new BusinessException(ResponseMessage.UserNotLogin);
                }
            }else{
                if (!ObjectUtils.isEmpty(checkOrIgnoreUrl)
                        && pathContainsUrl(checkOrIgnoreUrl, path)){
                    throw new BusinessException(ResponseMessage.UserNotLogin);
                }
            }
        }
        return true;
    }

    protected boolean pathContainsUrl(List<String> urls, String path) {
        for (String url : urls) {
            if (path.contains(url)) {
                return true;
            }
        }
        return false;

    }


    protected void userNotLogin(HttpServletResponse response) {

        AbstractServiceResponse result = new AbstractServiceResponse();
        result.setCode("0000");
        result.setMessage("用户未登录");
        result.setIsException(false);
        result.setIsSuccess(false);

        writeJsonError(response, result);

    }

    protected BaseUserEntity loadUser(HttpServletRequest request, HttpServletResponse response) {

        BaseUserEntity user = null;
        //如果不是cookie存储，那就从请求头里面传输
        String tk = request.getHeader(ContextConstants.request_cookie_token);
        if (StringUtils.isNotEmpty(tk)) {
            Token token = Token.parseToken(tk);
            user = userManager.findUserByAuthKey(token.getAuthKey());
            initContext(token, user);
        }
        Cookie cookie = CookieHelper.getCookie(request, ContextConstants.request_cookie_token);
        if (cookie != null && user == null) {
            Token token = Token.parseToken(cookie.getValue());
            if (token != null) {
                user = userManager.findUserByAuthKey(token.getAuthKey());
                initContext(token, user);
                if (!token.isExpired()) {
                    user = userManager.findUserByAuthKey(token.getAuthKey());
                    //设置线程环境
                    initContext(token, user);
                    token.reloadExpireTime(userManager.getTokenExpire());
                    CookieHelper.addUserLoginTokenToCookie(request, response, token);
                    userManager.updateAuthKeyExpire(token.getAuthKey(), userManager.getTokenExpire());
                } else {
                    //如果已经过期则把redis的authkey也删除
                    userManager.deleteUserLoginAuthKey(token.getAuthKey());
                    CookieHelper.invalidateUserLoginTokenCookie(request, response);
                }
            }
        }
        return user;
    }

    protected void initContext(Token token, BaseUserEntity user) {
        if (user != null && token != null) {
            RequestContext req = CurrentContext.getRequestContext();
            req.setCpyCode(user.getCpyCode());
            req.setUserInfo(user);
            req.setUserCode(user.getUserCode());
            req.setAuthKey(token.getAuthKey());
            req.setToken(token);
        }
    }

    public List<String> getCheckOrIgnoreUrl() {
        return checkOrIgnoreUrl;
    }

    public void setCheckOrIgnoreUrl(List<String> checkOrIgnoreUrl) {
        this.checkOrIgnoreUrl = checkOrIgnoreUrl;
    }

    public IBaseUserManager getUserManager() {
        return userManager;
    }

    public void setUserManager(IBaseUserManager userManager) {
        this.userManager = userManager;
    }

    public Boolean getCheck() {
        return check;
    }

    public void setCheck(Boolean check) {
        this.check = check;
    }
}
